/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			uvarint.cc
  \date			Dec 2011
  \author		TNick

  \brief		Contains the implementation for UVarInt class


*//*


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<QSettings>

#include	<pgscript.h>
#include	<pgscript_internal.h>

#include	<pgsave/ipgsave.h>

#include	"uvarint.h"

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  DEFINITIONS    --------------------------------------------------------- */

using namespace PgScr;
using namespace PgSave;

/*  DEFINITIONS    ========================================================= */
//
//
//
//
/*  DATA    ---------------------------------------------------------------- */

/*  DATA    ================================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/* ------------------------------------------------------------------------- */
UVarInt::UVarInt		( void )
	: DefVar()
{
	/* stub */
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
UVarInt::~UVarInt		( void )
{
	/* stub */
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
void				UVarInt::setDefault		( VarStore * uv )
{
	Q_ASSERT( uv->ty == VTY_INTEGER );
	uv->l = 0;
}
/* ========================================================================= */



/* ------------------------------------------------------------------------- */
bool				UVarInt::convToBool		( bool * b_ok, VarStore * uv )
{
	*b_ok = true;
	if ( uv->l == 0 )
		return false;
	else
		return true;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
qint16				UVarInt::convToShort		( bool * b_ok, VarStore * uv )
{
	if ( ( uv->l > 32767 ) || ( uv->l < -32768 ) )
	{
		b_ok = false;
		return 0;
	}

	*b_ok = true;
	return (qint16)uv->l ;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
qint32				UVarInt::convToInt		( bool * b_ok, VarStore * uv )
{

	qint64 ulim = 8;// 0x80000000 - 1
	ulim = ulim << 28;
	qint64 llim = ulim * (-1);// 0x80000000 * -1
	ulim--;
	if ( ( uv->l > ulim ) || ( uv->l < llim ) )
	{
		b_ok = false;
		return 0;
	}

	*b_ok = true;
	return (qint32)uv->l ;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
qint64				UVarInt::convToLong		( bool * b_ok, VarStore * uv )
{
	*b_ok = true;
	return uv->l ;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
qint8				UVarInt::convToByte		( bool * b_ok, VarStore * uv )
{
	if ( ( uv->l > 127 ) || ( uv->l < -128 ) )
	{
		b_ok = false;
		return 0;
	}

	*b_ok = true;
	return (qint8)uv->l ;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
qreal				UVarInt::convToDouble		( bool * b_ok, VarStore * uv )
{
	*b_ok = true;
	return (qreal)uv->l ;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QStringList			UVarInt::convToStrLst		( bool * b_ok, VarStore * uv )
{
	*b_ok = true;
	return QStringList( QString::number( uv->l ) );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QString				UVarInt::convToStr		( bool * b_ok, VarStore * uv )
{
	*b_ok = true;
	return QString::number( uv->l );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
QString				UVarInt::presentation	( VarStore * uv )
{

	/* we should have been provided with an variable */
	Q_ASSERT ( uv != NULL );

	/* and that the type should have been a proper one */
	Q_ASSERT( uv->ty == VTY_INTEGER );

	return QString::number( uv->l );
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool		UVarInt::load			( PgSave::IPgSave & stg, VarStore * uv )
{
	resetContent( uv );

	bool		b_ret = true;
	if ( stg.getStr( TAG_NAME_TYPE, &b_ret ) != typeName( uv ) )
		return false;
	if ( ! b_ret ) return false;

	uv->l = stg.getInt( TAG_NAME_VALUE, &b_ret );
	return b_ret;

}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool		UVarInt::save			( PgSave::IPgSave & stg, VarStore * uv )
{
	bool		b_ret = true;

	b_ret &= stg.set( TAG_NAME_TYPE,	typeName( uv ) );
	b_ret &= stg.set( TAG_NAME_VALUE,	uv->l );

	return b_ret;
}
/* ========================================================================= */

/* ------------------------------------------------------------------------- */
bool		UVarInt::blindCreate	 (
		IPgSave * intf, QString s_path, void * kb_data )
{
	BlindData * bd = (BlindData*)kb_data;
	Q_ASSERT( bd != NULL );
	Q_ASSERT( s_path.length() > 0 );

	/* get the value; fail if can't convert */
	bool b_pk;
	qint64 i_val = intf->getLong( s_path, &b_pk );
	if ( ! b_pk ) return false;

	switch( bd->ty_ )	{
	case	BT_SAVE_HERE:	{
		bd->local.l = i_val;
		bd->local.ty = VTY_INTEGER;
	break; }
	case	BT_IN_VAR:	{
		Q_ASSERT( bd->var != NULL );
		bd->var->changeVal( i_val );
		break; }
	case	BT_NEW_IN_MODULE:	{
		int i = s_path.lastIndexOf( "/" );
		if ( i == -1 ) i = 0;
		QString s_name = s_path.mid( i );
		bd->var = new UserVar( s_name, bd->mdl );
		bd->var->setVal( i_val );
		break; }
	default:
		Q_ASSERT( false );
	}

	return true;
}
/* ========================================================================= */



#ifdef	PGSCRIPT_TESTS
/* ------------------------------------------------------------------------- */
void				PgScr::VarInt_Tests					(
		int & performed, int & succeded )
{
	QString Outcm;
	performed = 0;
	succeded = 0;

	bool b_conv_ok = false;
	bool b_ok = false;

	UserVar * p_var;
	p_var = new UserVar( );

	qDebug() << "Now testing integer representation";

	for (;;)	{
		p_var->setVal( (int)65 );

		bool b_res = p_var->convToBool( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( b_res != true )			break;

		qint16 i16  = p_var->convToShort( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( i16 != 65 )				break;

		qint32 i32 = p_var->convToInt( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( i32 != 65 )				break;

		qint64 i64 = p_var->convToLong( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( i64 != 65 )				break;

		qint8 i8 = p_var->convToByte( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( i8 != 65 )					break;

		double dbl = p_var->convToDouble( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( dbl != 65 )				break;

		QStringList sl = p_var->convToStrLst( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( sl.count() != 1 )			break;
		if ( sl.at( 0 ) != "65" )		break;

		QString s = p_var->convToStr( &b_conv_ok, &p_var->data_ );
		if ( b_conv_ok == false )		break;
		if ( s != "65" )				break;

		b_ok = true;
		break;
	}
	if ( b_ok )	TEST_OK
			else	TEST_FAIL
			qDebug() << QString( " - convTo__ ..." )
					 << Outcm;
	performed++; b_ok = true;


	delete p_var;}
/* ========================================================================= */
#endif

/*  CLASS    =============================================================== */
//
//
//
//
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
